home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / widgets-mesa / demos / ed.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-31  |  21.1 KB  |  789 lines

  1. /* ed.c -- Event Display (demo program for the MesaWS widget)
  2.    Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2 of the License, or
  7.    (at your option) any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; see the file COPYING.  If not, write to
  16.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.    $Id: ed.c,v 1.18 1996/09/27 10:21:53 ohl Exp $
  19.  */
  20.  
  21. /* This is a simple event display as a demonstration of the MesaWS widget.
  22.    It reads a stream of simple event records from standard input (see the
  23.    file `events' for a example).
  24.  
  25.    It is a slow and crude hack.  */
  26.   
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <stdarg.h>
  30. #include <math.h>
  31. #ifndef M_PI
  32. #define M_PI 3.14159265358979323846
  33. #endif
  34. #include <X11/X.h>
  35. #include <X11/Intrinsic.h>
  36. #include <X11/StringDefs.h>
  37. #include <X11/Shell.h>
  38. #ifndef __GLX_MOTIF
  39. #include <X11/Xaw/Box.h>
  40. #include <X11/Xaw/Command.h>
  41. #include <X11/Xaw/Form.h>
  42. #include <GL/xmesa.h>
  43. #include <GL/gl.h>
  44. #include <GL/glu.h>
  45. #include <GL/glx.h>
  46. #include <GL/MesaDrawingArea.h>
  47. #include <GL/MesaWorkstation.h>
  48. #else /* __GLX_MOTIF */
  49. #include <Xm/RowColumn.h>
  50. #include <Xm/Label.h>
  51. #include <Xm/PushB.h>
  52. #include <Xm/Form.h>
  53. #include <GL/xmesa.h>
  54. #include <GL/gl.h>
  55. #include <GL/glu.h>
  56. #include <GL/glx.h>
  57. #include <GL/MesaMDrawingArea.h>
  58. #include <GL/MesaMWorkstation.h>
  59. #define GLwMakeCurrent GLwMMakeCurrent
  60. #define GLwPostObject           GLwMPostObject
  61. #define GLwBeginView           GLwMBeginView
  62. #define GLwEndView           GLwMEndView
  63. #define GLwSetPolarView           GLwMSetPolarView
  64. #define GLwBeginProjection       GLwMBeginProjection
  65. #define GLwEndProjection       GLwMEndProjection
  66. #define GLwSetFrustumProjection       GLwMSetFrustumProjection
  67. #define GLwGetProjectionList       GLwMGetProjectionList
  68. #define GLwRedrawObjects       GLwMRedrawObjects
  69. #define GLwPostProjection       GLwMPostProjection
  70. #endif /* __GLX_MOTIF */
  71.  
  72. static char *RCS_Id =
  73. "@(#) $Id: ed.c,v 1.18 1996/09/27 10:21:53 ohl Exp $";
  74.  
  75. static GLint Black, White, Red, Green, Blue, Yellow;
  76. Widget mesa, mesax, mesay, mesaz;
  77.  
  78. static void quit_function (Widget, XtPointer, XtPointer);
  79. static void next_function (Widget, XtPointer, XtPointer);
  80. static void next_event (void);
  81. static void update_angles (float, float);
  82. static void update_number (int);
  83.  
  84. static void
  85. Quit (Widget w, XEvent *event, String *argv, Cardinal *argc)
  86. {
  87.   quit_function (NULL, NULL, NULL);
  88. }
  89.  
  90. void
  91. Next (Widget w, XEvent *event, String *argv, Cardinal *argc)
  92. {
  93.   next_function (NULL, NULL, NULL);
  94. }
  95.  
  96. static XtActionsRec actions[] =
  97. {
  98.   {"Quit", Quit },
  99.   {"Next", Next },
  100. };
  101.  
  102. void
  103. quit_function (Widget w, XtPointer closure, XtPointer call_data)
  104. {
  105.   exit (0);
  106. }
  107.  
  108. void
  109. next_function (Widget w, XtPointer closure, XtPointer call_data)
  110. {
  111.   next_event ();
  112.   GLwRedrawObjects (mesa);
  113.   GLwRedrawObjects (mesax);
  114.   GLwRedrawObjects (mesay);
  115.   GLwRedrawObjects (mesaz);
  116. }
  117.  
  118. #define SET_POLAR(_p, _r, _theta, _phi) \
  119.     (_p)[0] = (_r) * sin (_theta) * cos (_phi), \
  120.     (_p)[1] = (_r) * sin (_theta) * sin (_phi), \
  121.     (_p)[2] = (_r) * cos (_theta)
  122. static void
  123. draw_barrel_segment (float bottom_radius, float top_radius,
  124.              float front_angle, float back_angle,
  125.              float half_angle)
  126. {
  127.   int i;
  128.   GLdouble top[4][3], bottom[4][3], *front[4], *back[4];
  129.  
  130.   SET_POLAR (top[0], top_radius, front_angle, half_angle);
  131.   SET_POLAR (top[1], top_radius, front_angle, -half_angle);
  132.   SET_POLAR (top[2], top_radius, back_angle, -half_angle);
  133.   SET_POLAR (top[3], top_radius, back_angle, half_angle);
  134.  
  135.   SET_POLAR (bottom[0], bottom_radius, front_angle, half_angle);
  136.   SET_POLAR (bottom[1], bottom_radius, front_angle, -half_angle);
  137.   SET_POLAR (bottom[2], bottom_radius, back_angle, -half_angle);
  138.   SET_POLAR (bottom[3], bottom_radius, back_angle, half_angle);
  139.  
  140.   front[0] = top[0];
  141.   front[1] = top[1];
  142.   front[2] = bottom[1];
  143.   front[3] = bottom[0];
  144.  
  145.   back[0] = top[3];
  146.   back[1] = top[2];
  147.   back[2] = bottom[2];
  148.   back[3] = bottom[3];
  149.  
  150.   glBegin (GL_LINE_LOOP);
  151.     for (i = 0; i <= 3; i++)
  152.       glVertex3dv (top[i]);
  153.   glEnd ();
  154.   
  155.   glBegin (GL_LINE_LOOP);
  156.     for (i = 0; i <= 3; i++)
  157.       glVertex3dv (bottom[i]);
  158.   glEnd ();
  159.   
  160.   glBegin (GL_LINE_LOOP);
  161.     for (i = 0; i <= 3; i++)
  162.       glVertex3dv (front[i]);
  163.   glEnd ();
  164.   
  165.   glBegin (GL_LINE_LOOP);
  166.     for (i = 0; i <= 3; i++)
  167.       glVertex3dv (back[i]);
  168.   glEnd ();
  169. }
  170.  
  171. static GLuint particles;
  172. static GLuint greek, latin, desc, desc_number, desc_angles;
  173.  
  174. static void
  175. next_event (void)
  176. {
  177.   char buffer[100];
  178.   enum
  179.     {
  180.       SKIP, READ, DONE
  181.     }
  182.   state;
  183.   int event = 0;
  184.   
  185.   glNewList (particles, GL_COMPILE);
  186.   glBegin (GL_LINES);
  187.   {
  188.     state = SKIP;
  189.     while (state != DONE)
  190.       {
  191.     int id;
  192.     float px, py, pz;
  193.     if (fgets (buffer, 100, stdin) == NULL)
  194.       state = DONE;
  195.     switch (state)
  196.       {
  197.       case SKIP:
  198.         if (sscanf (buffer, "BEGIN %d", &event) == 1)
  199.           state = READ;
  200.         break;
  201.       case READ:
  202.         if (sscanf (buffer, "%d %g %g %g",
  203.             &id, &px, &py, &pz) == 4)
  204.           {
  205.         if (id == 22)
  206.           {
  207.             /* Photons */
  208.             glIndexi (Red);
  209.             glColor3f (1.0, 0.0, 0.0);
  210.           }
  211.         else if ((11 == abs (id))
  212.              || (13 == abs (id))
  213.              || (15 == abs (id)))
  214.           {
  215.             /* Charged leptons */
  216.             glIndexi (Green);
  217.             glColor3f (0.0, 1.0, 0.0);
  218.           }
  219.         else if ((12 == abs (id))
  220.              || (14 == abs (id))
  221.              || (16 == abs (id)))
  222.           {
  223.             /* Neutral leptons */
  224.             glIndexi (Yellow);
  225.             glColor3f (1.0, 1.0, 0.0);
  226.           }
  227.         else if ((abs (id) <= 6) || (100 <= abs (id)))
  228.           {
  229.             /* Quarks/Hadrons */
  230.             glIndexi (Blue);
  231.             glColor3f (0.0, 0.0, 1.0);
  232.           }
  233.         else
  234.           {
  235.             /* ??? */
  236.             glIndexi (White);
  237.             glColor3f (1.0, 1.0, 1.0);
  238.           }
  239.         glVertex3f (0.0, 0.0, 0.0);
  240.         glVertex3f (px, py, pz);
  241.           }
  242.         else if (strncmp ("END", buffer, 3) == 0)
  243.           state = DONE;
  244.         break;
  245.       case DONE:
  246.         /* never happens */
  247.         break;
  248.       }
  249.       }
  250.   }
  251.   glEnd ();
  252.   glEndList ();
  253.  
  254.   update_number (event);
  255. }
  256.  
  257. static void
  258. update_angles (float theta, float phi)
  259. {
  260.   char msg[64];
  261.   sprintf (msg, "f=%5.2fp, q=%5.2fp", phi/M_PI, theta/M_PI);
  262.   glNewList (desc_angles, GL_COMPILE);
  263.     glCallLists (strlen (msg), GL_BYTE, msg);
  264.   glEndList ();
  265. }  
  266.  
  267. static void
  268. update_number (int event)
  269. {
  270.   char msg[32];
  271.   sprintf (msg, "ADLO/TH, #%d", event);
  272.   glNewList (desc_number, GL_COMPILE);
  273.     glCallLists (strlen (msg), GL_BYTE, msg);
  274.   glEndList ();
  275. }  
  276.  
  277. static void
  278. setup_context (Widget w)
  279. {
  280.   GLwMakeCurrent (w);
  281.   glClearColor (0.0, 0.0, 0.0, 0.0);
  282.   glClearIndex (Black);
  283.   glShadeModel (GL_FLAT);
  284. }
  285.  
  286. static GLint
  287. alloc_color (Widget w, Colormap cmap, int red, int green, int blue)
  288.   XColor xcolor;
  289.   xcolor.red = red;
  290.   xcolor.green = green;
  291.   xcolor.blue = blue;
  292.   xcolor.flags = DoRed | DoGreen | DoBlue;
  293.   if (!XAllocColor (XtDisplay (w), cmap, &xcolor))
  294.     {
  295.       printf ("Couldn't allocate color!\n");
  296.       exit (1);
  297.     }
  298.   return xcolor.pixel;
  299. }
  300.  
  301. /* This is rather inefficient, but we don't mind for the moment,
  302.    because it works.  */
  303.  
  304. static void
  305. translate_pixels (Widget to, Widget from, ...)
  306. {
  307.   va_list ap;
  308.   char *name;
  309.   Colormap from_cmap, to_cmap;
  310.   XColor xcolor;
  311.  
  312.   XtVaGetValues (from, XtNcolormap, &from_cmap, NULL);
  313.   XtVaGetValues (to, XtNcolormap, &to_cmap, NULL);
  314.  
  315.   va_start (ap, from);
  316.   for (name = va_arg (ap, char *); name != NULL; name = va_arg (ap, char *))
  317.     {
  318.       XtVaGetValues (from, name, &xcolor.pixel, NULL);
  319.       XQueryColor (XtDisplay (from), from_cmap, &xcolor);
  320.       if (!XAllocColor (XtDisplay (to), to_cmap, &xcolor))
  321.     XtAppWarning (XtWidgetToApplicationContext (to),
  322.               "Couldn't allocate color!\n");
  323.       else
  324.     XtVaSetValues (from, name, xcolor.pixel, NULL);
  325.     }
  326.   va_end (ap);
  327. }
  328.  
  329. static Widget
  330. create_label (Widget parent, char *name, char *text)
  331. {
  332. #ifndef __GLX_MOTIF
  333.   return XtVaCreateManagedWidget (name, labelWidgetClass, parent,
  334.                   XtNlabel, text, NULL);
  335. #else /* __GLX_MOTIF */
  336.   XmString label = XmStringCreateLtoR (text, XmFONTLIST_DEFAULT_TAG);
  337.   return XtVaCreateManagedWidget (name, xmLabelWidgetClass, parent,
  338.                   XmNlabelString, label, NULL);
  339.   XmStringFree (label);
  340. #endif /* __GLX_MOTIF */
  341. }
  342.  
  343. static Widget
  344. create_ok (Widget parent, char *name, XtCallbackProc cb)
  345. {
  346.   Widget ok;
  347. #ifndef __GLX_MOTIF
  348.   ok = XtVaCreateManagedWidget (name, commandWidgetClass, parent,
  349.                 XtNlabel, "OK", NULL);
  350.   XtAddCallback (ok, XtNcallback, cb, NULL);
  351. #else /* __GLX_MOTIF */
  352.   XmString label = XmStringCreate ("OK", XmFONTLIST_DEFAULT_TAG);
  353.   ok = XtVaCreateManagedWidget (name, xmPushButtonWidgetClass, parent,
  354.                 XmNlabelString, label, NULL);
  355.   XmStringFree (label);
  356.   XtAddCallback (ok, XmNarmCallback, cb, NULL);
  357. #endif /* __GLX_MOTIF */
  358.   return ok;
  359. }
  360.  
  361. static Widget
  362. create_command (Widget parent, char *name, XtCallbackProc cb)
  363. {
  364.   Widget ok;
  365. #ifndef __GLX_MOTIF
  366.   ok = XtVaCreateManagedWidget (name, commandWidgetClass, parent, NULL);
  367.   XtAddCallback (ok, XtNcallback, cb, NULL);
  368. #else /* __GLX_MOTIF */
  369.   ok = XtVaCreateManagedWidget (name, xmPushButtonWidgetClass, parent, NULL);
  370.   XtAddCallback (ok, XmNarmCallback, cb, NULL);
  371. #endif /* __GLX_MOTIF */
  372.   return ok;
  373. }
  374.  
  375. static Widget
  376. create_popup (Widget parent, char *name)
  377. {
  378. #ifndef __GLX_MOTIF
  379.   return XtVaCreatePopupShell (name, transientShellWidgetClass, parent, NULL);
  380. #else /* __GLX_MOTIF */
  381.   /* ??? */
  382.   return XtVaCreatePopupShell (name, transientShellWidgetClass, parent, NULL);
  383. #endif /* __GLX_MOTIF */
  384. }
  385.  
  386. static Widget
  387. create_box (Widget parent, char *name)
  388. {
  389. #ifndef __GLX_MOTIF
  390.   return XtVaCreateManagedWidget (name, boxWidgetClass, parent,
  391.                   XtNorientation, XtorientVertical, NULL);
  392. #else /* __GLX_MOTIF */
  393.   return XtVaCreateManagedWidget (name, xmRowColumnWidgetClass, parent,
  394.                   XmNorientation, XmVERTICAL, NULL);
  395. #endif /* __GLX_MOTIF */
  396. }
  397.  
  398.    
  399. Widget about_shell, help_shell;
  400.  
  401. char about_message[] = "\
  402. This is ed, a simple particle physics event display\n\
  403. application and demo for the MesaWorkstation widget.\n\
  404. \n\
  405. Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de\n\
  406. \n\
  407. This is free software; see the source for copying conditions.\n\
  408. There is NO warranty; not even for MERCHANTABILITY\n\
  409. or FITNESS FOR A PARTICULAR PURPOSE.";
  410.  
  411. void
  412. popup_about (Widget w, XtPointer closure, XtPointer call_data)
  413. {
  414.   XtPopup (about_shell, XtGrabNonexclusive);
  415. }
  416.  
  417. void
  418. popdown_about (Widget w, XtPointer closure, XtPointer call_data)
  419. {
  420.   XtPopdown (about_shell);
  421. }
  422.  
  423.  
  424. char help_message[] = "\
  425. Sorry, no online help available yet.\n\
  426. \n\
  427. See the manpage or the source of the MesaWorkstation widget\n\
  428. for the available keystroke translations and their actions.\n\
  429. For a start, use the cursor keys to rotate the object.\n\
  430. \n\
  431. The color code of the particles is as follows:\n\
  432. \n\
  433.   red:    photons\n\
  434.   green:  charged leptons (electrons, muons, taus)\n\
  435.   yellow: neutrinos\n\
  436.   blue:   hadrons (incl. quarks)\n\
  437.   while:  unidentified\n";
  438.  
  439. void
  440. popup_help (Widget w, XtPointer closure, XtPointer call_data)
  441. {
  442.   XtPopup (help_shell, XtGrabNonexclusive);
  443. }
  444.  
  445. void
  446. popdown_help (Widget w, XtPointer closure, XtPointer call_data)
  447. {
  448.   XtPopdown (help_shell);
  449. }
  450.  
  451.  
  452. static XrmOptionDescRec options[] =
  453. {
  454.   { "-debug", "*debug", XrmoptionNoArg, "True" },
  455.   { "-rgba", "*rgba", XrmoptionNoArg, "True" },
  456.   { "-doublebuffer", "*doublebuffer", XrmoptionNoArg, "True" },
  457.   { "-ximage", "*ximage", XrmoptionNoArg, "True" },
  458. };
  459.  
  460. static String fallback_resources[] =
  461. {
  462. #ifndef __GLX_MOTIF
  463.   "*MesaWorkstation.debug: false",
  464.   "*MesaWorkstation.rgba: false",
  465.   "*MesaWorkstation.installColormap: true",
  466.   "*MesaWorkstation.doublebuffer: true",
  467.   "*MesaWorkstation.ximage: false",
  468.   "*MesaWorkstation.translations: #augment \
  469.    <Key>q: Quit()\n\
  470.    <Key>Return: Next()\n\
  471.    <Key>space: Next()",
  472. #else /* __GLX_MOTIF */
  473.   "*MesaMWorkstation.debug: false",
  474.   "*MesaMWorkstation.rgba: false",
  475.   "*MesaMWorkstation.installColormap: true",
  476.   "*MesaMWorkstation.doublebuffer: true",
  477.   "*MesaMWorkstation.ximage: false",
  478.   "*MesaMWorkstation.translations: #augment \
  479.    <Key>q: Quit()\n\
  480.    <Key>Return: Next()\n\
  481.    <Key>space: Next()",
  482. #endif /* __GLX_MOTIF */
  483.   "*help.label: Help",
  484.   "*about.label: About ed",
  485.   "*quit.label: Exit",
  486.   "*next.label: Next event",
  487.   "*mesa.width: 400",
  488.   "*mesa.height: 400",
  489.   "*mesax.width: 100",
  490.   "*mesax.height: 100",
  491.   "*mesay.width: 100",
  492.   "*mesay.height: 100",
  493.   "*mesaz.width: 100",
  494.   "*mesaz.height: 100",
  495.   NULL
  496. };
  497.  
  498. int
  499. main (int argc, char *argv[])
  500. {
  501.   Widget top, frame, commands, next, quit;
  502.   Widget about, about_box, about_text, about_id, about_ok;
  503.   Widget help, help_box, help_text, help_ok;
  504.   XtAppContext app_context;
  505.   Boolean rgba, cmap_installed;
  506.   
  507.   GLuint barrel, object;
  508.  
  509.   XtSetLanguageProc (NULL, NULL, NULL);
  510.   top = XtVaAppInitialize (&app_context, "Ed",
  511.                options, XtNumber (options),
  512.                &argc, argv, fallback_resources,
  513.                NULL);
  514.  
  515. #ifndef __GLX_MOTIF
  516.   frame = XtVaCreateManagedWidget ("frame", formWidgetClass,
  517.                    top,
  518.                    NULL);
  519.   commands = XtVaCreateManagedWidget ("commands", boxWidgetClass,
  520.                       frame,
  521.                       XtNhSpace, 10,
  522.                       XtNorientation, XtorientHorizontal,
  523.                       NULL);
  524. #else /* __GLX_MOTIF */
  525.   frame = XtVaCreateManagedWidget ("frame", xmFormWidgetClass,
  526.                    top,
  527.                    /* This should not be necessary.  Is it
  528.                       a bug in LessTif or in my understanding
  529.                       of Motif?  */
  530.                    XtNwidth, 420, XtNheight, 600,
  531.                     NULL);
  532.   commands = XtVaCreateManagedWidget ("commands", xmRowColumnWidgetClass,
  533.                       frame,
  534.                       XmNorientation, XmHORIZONTAL,
  535.                       XmNtopAttachment, XmATTACH_FORM,
  536.                       XmNtopOffset, 10,
  537.                       XmNrightAttachment, XmATTACH_FORM,
  538.                       XmNrightOffset, 10,
  539.                       NULL);
  540. #endif /* __GLX_MOTIF */
  541.  
  542.   help = create_command (commands, "help", popup_help);
  543.   help_shell = create_popup (top, "help_shell");
  544.   help_box = create_box (help_shell, "help_box");
  545.   help_text = create_label (help_box, "help_text", help_message);
  546.   help_ok = create_ok (help_box, "help_ok", popdown_help);
  547.  
  548.   about = create_command (commands, "about", popup_about);
  549.   about_shell = create_popup (top, "about_shell");
  550.   about_box = create_box (about_shell, "about_box");
  551.   about_text = create_label (about_box, "about_text", about_message);
  552.   about_id = create_label (about_box, "about_id", RCS_Id);
  553.   about_ok = create_ok (about_box, "about_ok", popdown_about);
  554.  
  555.   next = create_command (commands, "next", next_function);
  556.   quit = create_command (commands, "quit", quit_function);
  557.  
  558. #ifndef __GLX_MOTIF
  559.   mesa = XtVaCreateManagedWidget ("mesa", mesaWorkstationWidgetClass,
  560.                   frame,
  561.                   GLwNshareLists, True,
  562.                   XtNfromVert, commands, XtNvertDistance, 10,
  563.                   NULL);
  564.   mesax = XtVaCreateManagedWidget ("mesax", mesaWorkstationWidgetClass,
  565.                    frame,
  566.                    GLwNshareLists, True,
  567.                    XtNfromVert, mesa, XtNvertDistance, 10,
  568.                    NULL);
  569.   mesay = XtVaCreateManagedWidget ("mesay", mesaWorkstationWidgetClass,
  570.                    frame,
  571.                    GLwNshareLists, True,
  572.                    XtNfromVert, mesa, XtNvertDistance, 10,
  573.                    XtNfromHoriz, mesax, XtNhorizDistance, 50,
  574.                    NULL);
  575.   mesaz = XtVaCreateManagedWidget ("mesaz", mesaWorkstationWidgetClass,
  576.                    frame,
  577.                    GLwNshareLists, True,
  578.                    XtNfromVert, mesa, XtNvertDistance, 10,
  579.                    XtNfromHoriz, mesay, XtNhorizDistance, 50,
  580.                    NULL);
  581. #else /* __GLX_MOTIF */
  582.   mesa = XtVaCreateManagedWidget ("mesa", mesaMWorkstationWidgetClass,
  583.                   frame,
  584.                   GLwNshareLists, True,
  585.                   XmNtopAttachment, XmATTACH_WIDGET,
  586.                   XmNtopOffset, 10,
  587.                   XmNtopWidget, commands,
  588.                   XmNleftAttachment, XmATTACH_FORM,
  589.                   XmNleftOffset, 10,
  590.                   XmNrightAttachment, XmATTACH_FORM,
  591.                   XmNrightOffset, 10,
  592.                   NULL);
  593.   mesax = XtVaCreateManagedWidget ("mesax", mesaMWorkstationWidgetClass,
  594.                    frame,
  595.                    GLwNshareLists, True,
  596.                    XmNtopAttachment, XmATTACH_WIDGET,
  597.                    XmNtopOffset, 10,
  598.                    XmNtopWidget, mesa,
  599.                    XmNleftAttachment, XmATTACH_FORM,
  600.                    XmNleftOffset, 10,
  601.                    XmNbottomAttachment, XmATTACH_FORM,
  602.                    XmNbottomOffset, 10,
  603.                    NULL);
  604.   mesay = XtVaCreateManagedWidget ("mesay", mesaMWorkstationWidgetClass,
  605.                    frame,
  606.                    GLwNshareLists, True,
  607.                    XmNtopAttachment, XmATTACH_WIDGET,
  608.                    XmNtopOffset, 10,
  609.                    XmNtopWidget, mesa,
  610.                    XmNleftAttachment, XmATTACH_WIDGET,
  611.                    XmNleftOffset, 50,
  612.                    XmNleftWidget, mesax,
  613.                    XmNbottomAttachment, XmATTACH_FORM,
  614.                    XmNbottomOffset, 10,
  615.                    NULL);
  616.   mesaz = XtVaCreateManagedWidget ("mesaz", mesaMWorkstationWidgetClass,
  617.                    frame,
  618.                    GLwNshareLists, True,
  619.                    XmNtopAttachment, XmATTACH_WIDGET,
  620.                    XmNtopOffset, 10,
  621.                    XmNtopWidget, mesa,
  622.                    XmNleftAttachment, XmATTACH_WIDGET,
  623.                    XmNleftOffset, 50,
  624.                    XmNleftWidget, mesay,
  625.                    XmNbottomAttachment, XmATTACH_FORM,
  626.                    XmNbottomOffset, 10,
  627.                    XmNrightAttachment, XmATTACH_FORM,
  628.                    XmNrightOffset, 10,
  629.                    NULL);
  630. #endif /* __GLX_MOTIF */
  631.  
  632.   XtAppAddActions (app_context, actions, XtNumber (actions));
  633.   
  634.   XtRealizeWidget (top);
  635.  
  636.   XtVaGetValues (mesa,
  637.          GLwNrgba, &rgba,
  638.          GLwNinstallColormap, &cmap_installed,
  639.          NULL);
  640.   if (rgba)
  641.     {
  642.       Black = White = Red = Green = Blue = Yellow = 0;
  643.  
  644.       if (cmap_installed)
  645.     {
  646.       /* In RGBA mode, the Mesa widgets will have their own color map.
  647.          Adjust the colors of the other widgets so that--even if the rest
  648.          of the screen has wrong colors--all application widgets have the
  649.          right colors.  */
  650.              
  651.       translate_pixels (mesa, quit,
  652.                 XtNbackground, XtNforeground, XtNborder, NULL);
  653.       translate_pixels (mesa, next,
  654.                 XtNbackground, XtNforeground, XtNborder, NULL);
  655.       translate_pixels (mesa, help,
  656.                 XtNbackground, XtNforeground, XtNborder, NULL);
  657.       translate_pixels (mesa, about,
  658.                 XtNbackground, XtNforeground, XtNborder, NULL);
  659.       translate_pixels (mesa, commands, XtNbackground, XtNborder, NULL);
  660.       translate_pixels (mesa, frame, XtNbackground, XtNborder, NULL);
  661.       
  662.       /* Finally warp the pointer into the mesa widget, to make sure that
  663.          the user sees the right colors at the beginning.  */
  664.  
  665.       XWarpPointer (XtDisplay (mesa), None, XtWindow (mesa), 0, 0, 0, 0, 0, 0);
  666.     }
  667.     }
  668.   else
  669.     {
  670.       /* Allocate a few colors for use in color index mode.  */
  671.  
  672.       Colormap cmap;
  673.       cmap = DefaultColormap (XtDisplay (top), DefaultScreen (XtDisplay (top)));
  674.       Black  = alloc_color (top, cmap, 0x0000, 0x0000, 0x0000);
  675.       White  = alloc_color (top, cmap, 0xffff, 0xffff, 0xffff);
  676.       Red    = alloc_color (top, cmap, 0xffff, 0x0000, 0x0000);
  677.       Green  = alloc_color (top, cmap, 0x0000, 0xffff, 0x0000);
  678.       Blue   = alloc_color (top, cmap, 0x0000, 0x0000, 0xffff);
  679.       Yellow = alloc_color (top, cmap, 0xffff, 0xffff, 0x0000);
  680.     }
  681.  
  682.   setup_context (mesa);
  683.   setup_context (mesax);
  684.   setup_context (mesay);
  685.   setup_context (mesaz);
  686.  
  687.   GLwSetFrustumProjection (mesa, -1.0, 1.0, -1.0, 1.0, 1.0, 10.0);
  688.   GLwSetPolarView (mesa, 3, M_PI/2, 0.0);
  689.  
  690.   GLwBeginProjection (mesax);
  691.   glOrtho (-1.5, 1.5, -1.5, 1.5, 1.0, 10.0);
  692.   GLwEndProjection ();
  693.   GLwPostProjection (mesay, GLwGetProjectionList (mesax));
  694.   GLwPostProjection (mesaz, GLwGetProjectionList (mesax));
  695.  
  696.   GLwBeginView (mesax);
  697.   gluLookAt (3.0, 0.0, 0.0,  0.0, 0.0, 0.0,  0.0, 1.0, 0.0);
  698.   GLwEndView ();
  699.  
  700.   GLwBeginView (mesay);
  701.   gluLookAt (0.0, 3.0, 0.0,  0.0, 0.0, 0.0,  0.0, 0.0,-1.0);
  702.   GLwEndView ();
  703.  
  704.   GLwBeginView (mesaz);
  705.   gluLookAt (0.0, 0.0, 3.0,  0.0, 0.0, 0.0,  0.0, 1.0, 0.0);
  706.   GLwEndView ();
  707.  
  708.   barrel = glGenLists (1);
  709.   glNewList (barrel, GL_COMPILE);
  710.   {
  711.     draw_barrel_segment (0.9, 1.0,
  712.              0.3 * M_PI, 0.7 * M_PI,
  713.              0.1 * M_PI);
  714.   }
  715.   glEndList ();
  716.  
  717.   particles = glGenLists (1);
  718.   glNewList (particles, GL_COMPILE);
  719.   glEndList ();
  720.  
  721.   object = glGenLists (1);
  722.   glNewList (object, GL_COMPILE);
  723.   {
  724.     float frac;
  725.     glClear (GL_COLOR_BUFFER_BIT);
  726.     glIndexi (White);
  727.     glColor3f (1.0, 1.0, 1.0);
  728.     for (frac = 0; frac < 1.0; frac += 0.125)
  729.       {
  730.     glPushMatrix ();
  731.       glRotatef (frac * 360, 0.0, 0.0, 1.0);
  732.       glCallList (barrel);
  733.     glPopMatrix ();
  734.       }
  735.     glPushMatrix ();
  736.       glCallList (particles);
  737.     glPopMatrix ();
  738.   }
  739.   glEndList ();
  740.  
  741. #if 0
  742.   greek = glGenLists (128);
  743.   glXUseXFont (XLoadFont (XtDisplay (top), "*-symbol-*-240-*"),
  744.            0, 128, greek);
  745. #endif
  746.   latin = glGenLists (128);
  747.   glXUseXFont (XLoadFont (XtDisplay (top), "*-times-*-240-*"),
  748.            0, 128, latin);
  749.  
  750.   desc_number = glGenLists (1);
  751.   update_number (0);
  752.   desc_angles = glGenLists (1);
  753.   update_angles (0.0, 0.0);
  754.  
  755.   desc = glGenLists (1);
  756.   glNewList (desc, GL_COMPILE);
  757.   {
  758.     glMatrixMode (GL_PROJECTION);
  759.     glLoadIdentity ();
  760.     glOrtho (0, 400, 0, 400, -1.0, 1.0);
  761.     glMatrixMode (GL_MODELVIEW);
  762.     glLoadIdentity ();
  763.     glIndexi (White);
  764.     glColor3f (1.0, 1.0, 1.0);
  765.     glPushAttrib (GL_LIST_BIT);
  766.       glRasterPos2i (10.0, 10.0);
  767.       glListBase (latin);
  768.       glCallList (desc_number);
  769. #if 0
  770.       glRasterPos2i (10.0, 380.0);
  771.       glListBase (greek);
  772.       glCallList (desc_angles);
  773. #endif
  774.     glPopAttrib ();
  775.   }
  776.   glEndList ();
  777.   
  778.   GLwPostObject (mesa, object);
  779.   GLwPostObject (mesax, object);
  780.   GLwPostObject (mesay, object);
  781.   GLwPostObject (mesaz, object);
  782.   GLwPostObject (mesa, desc);
  783.  
  784.   XtAppMainLoop (app_context);
  785.   return (0);
  786. }
  787.  
  788.